package com.yuchen.core.jdbc;


import com.yuchen.core.MyPager;
import org.apache.commons.lang.StringUtils;
import org.nutz.dao.Condition;
import org.nutz.dao.Sqls;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.sql.SqlCallback;
import org.nutz.dao.sql.VarSet;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;

/**
 * @author Jack Q
 */
public class BaseDao extends NutDao {

    public MyPager queryPager(Class obj, Condition cnd, MyPager myPager) {
        Pager pager = createPager(myPager.getPageNo(), myPager.getPageSize());
        List list = query(obj, cnd, pager);
        myPager.setRecords(list);
        myPager.setTotalRecord(count(obj, cnd));
        return myPager;
    }

    public MyPager queryPager(String sql, Map<String, Object> params, MyPager myPager) {
        return makeMyPager(sql,params,myPager,true);
    }

    public MyPager queryLimitPager(String sql, Map<String, Object> params, int limit) {
        MyPager myPager = new MyPager();
        myPager.setPageSize(limit);
        return makeMyPager(sql,params,myPager,false);
    }

    public List querySql(String sql, Map<String, Object> params) {
        Sql sqlDB = makeSql(sql, params);
        sqlDB.setCallback(Sqls.callback.records());
        execute(sqlDB);
        return (List) sqlDB.getResult();
    }


    public int count(String sql, Map<String, Object> params) {
        sql = prepareCountHql(sql);
        Sql sqlDB = makeSql(sql, params);
        sqlDB.setCallback(Sqls.callback.integer());
        execute(sqlDB);
        return (Integer) sqlDB.getResult();

    }

    //sum max ...
    public Object fn(String sql, Map<String, Object> params) {
        Sql sqlDB = makeSql(sql, params);
        sqlDB.setCallback(new SqlCallback() {
            public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
                if (rs.next()) {
                    return rs.getObject(1);
                }
                return 0;
            }
        });
        execute(sqlDB);
        return sqlDB.getResult();
    }

    private String prepareCountHql(String orgSql) {
        String fromHql = orgSql;
        //select子句与order by子句会影响count查询,进行简单的排除.
        fromHql = "from " + StringUtils.substringAfter(fromHql, "from");
        fromHql = StringUtils.substringBefore(fromHql, "order by");
        String countHql = "select count(*) " + fromHql;
        return countHql;
    }

    private Sql makeSql(String sql, Map<String, Object> params) {
        Sql sqlDB = Sqls.create(sql);
        VarSet vars = sqlDB.params();
        if (null != params && params.size() > 0) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                vars.set(entry.getKey(), entry.getValue());
            }
        }
        return sqlDB;
    }

    private MyPager makeMyPager(String sql, Map<String, Object> params,MyPager myPager,boolean isCount){
        Pager pager = createPager(myPager.getPageNo(), myPager.getPageSize());
        Sql sqlDB = makeSql(sql, params);
        sqlDB.setPager(pager);
        sqlDB.setCallback(Sqls.callback.records());
        execute(sqlDB);
        List results = (List) sqlDB.getResult();
        myPager.setRecords(results);
        if(isCount){
            myPager.setTotalRecord(count(sql, params));
        }
        return myPager;
    }

}

